package co.yixiang.yshop.module.order.service.feedback;

import cn.hutool.core.util.StrUtil;
import co.yixiang.yshop.framework.common.exception.ServiceException;
import co.yixiang.yshop.module.order.controller.app.feedback.vo.FeedbackCreateReqVO;
import co.yixiang.yshop.module.order.controller.app.feedback.vo.FeedbackAnalysisRespVO;
import co.yixiang.yshop.module.order.dal.dataobject.orderfeedback.OrderFeedbackDO;
import co.yixiang.yshop.module.order.dal.dataobject.storeorder.StoreOrderDO;
import co.yixiang.yshop.module.order.dal.dataobject.storeordercartinfo.StoreOrderCartInfoDO;
import co.yixiang.yshop.module.product.dal.dataobject.storeproduct.StoreProductDO;
import co.yixiang.yshop.module.product.dal.dataobject.storeproductattr.StoreProductAttrDO;
import co.yixiang.yshop.module.order.dal.mysql.orderfeedback.OrderFeedbackMapper;
import co.yixiang.yshop.module.order.dal.mysql.storeorder.StoreOrderMapper;
import co.yixiang.yshop.module.order.dal.mysql.storeordercartinfo.StoreOrderCartInfoMapper;
import co.yixiang.yshop.module.product.dal.mysql.storeproduct.StoreProductMapper;
import co.yixiang.yshop.module.product.dal.mysql.storeproductattr.StoreProductAttrMapper;
import co.yixiang.yshop.module.product.service.storeproductattr.AppStoreProductAttrService;
import java.net.http.HttpClient;
import java.net.URI;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;

import static co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil.exception;
import static co.yixiang.yshop.module.order.enums.ErrorCodeConstants.STORE_ORDER_NOT_EXISTS;

/**
 * 订单反馈 Service 实现类
 *
 * @author yshop
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class FeedbackServiceImpl implements FeedbackService {

    private final OrderFeedbackMapper orderFeedbackMapper;
    private final StoreOrderMapper storeOrderMapper;
    private final StoreOrderCartInfoMapper storeOrderCartInfoMapper;
    private final StoreProductMapper storeProductMapper;
    private final StoreProductAttrMapper storeProductAttrMapper;
    private final AppStoreProductAttrService appStoreProductAttrService;
    private final DashScopeProperties dashScopeProperties;

    private static final String COMPLETED_STATUS = "3";
    private static final AtomicLong idGenerator = new AtomicLong(System.currentTimeMillis());

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createFeedback(FeedbackCreateReqVO createReqVO) {
        // 1. 校验订单是否属于该用户且已完成
        // 使用与AppStoreOrderService相同的查询方式
        LambdaQueryWrapper<StoreOrderDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.and(i -> i.eq(StoreOrderDO::getOrderId, createReqVO.getOrderId())
                .or().eq(StoreOrderDO::getUnique, createReqVO.getOrderId())
                .or().eq(StoreOrderDO::getExtendOrderId, createReqVO.getOrderId()));
        wrapper.eq(StoreOrderDO::getUid, Long.valueOf(createReqVO.getUserId()));

        StoreOrderDO order = storeOrderMapper.selectOne(wrapper);
        if (order == null) {
            throw exception(STORE_ORDER_NOT_EXISTS);
        }

        if (!COMPLETED_STATUS.equals(order.getStatus().toString())) {
            throw new ServiceException(400, "订单未完成，无法提交反馈");
        }

        // 2. 获取订单中的第一个商品（简化处理，实际项目中可能需要多个商品分别处理）
        List<StoreOrderCartInfoDO> orderItems = storeOrderCartInfoMapper.selectList(
                "oid", order.getId());

        if (orderItems.isEmpty()) {
            throw new ServiceException(400, "订单中没有商品");
        }

        StoreOrderCartInfoDO firstItem = orderItems.get(0);
        StoreProductDO product = storeProductMapper.selectById(firstItem.getProductId());
        if (product == null) {
            throw new ServiceException(400, "商品信息不存在");
        }

        // 3. 检查是否是复购用户
        int purchaseCount = orderFeedbackMapper.countProductPurchase(createReqVO.getUserId(),
                firstItem.getProductId().toString(), createReqVO.getOrderId());
        boolean isRepeatPurchase = purchaseCount > 0;

        // 4. 插入反馈记录
        String feedbackId = generateFeedbackId();
        OrderFeedbackDO feedback = OrderFeedbackDO.builder()
                .id(feedbackId)
                .orderId(order.getId().toString())  // 保存数据库主键ID
                .userId(createReqVO.getUserId())
                .message(createReqVO.getMessage())
                .productId(firstItem.getProductId().toString())
                .productName(product.getStoreName())
                .analysisStatus("PENDING")
                .isRepeatPurchase(isRepeatPurchase)
                .createTime(LocalDateTime.now())
                .build();

        orderFeedbackMapper.insert(feedback);
        log.info("[createFeedback][用户({})对订单({})提交反馈：{}]",
                createReqVO.getUserId(), createReqVO.getOrderId(), createReqVO.getMessage());

        // 5. 异步处理AI分析（在后台进行，不影响用户体验）
        for (StoreOrderCartInfoDO item : orderItems) {
            processItemForRecommendationAsync(feedbackId, createReqVO.getUserId(),
                    order.getId().toString(), item.getProductId().toString(), createReqVO.getMessage());
        }

        return feedbackId;
    }

    /**
     * 生成反馈ID
     */
    private String generateFeedbackId() {
        return String.valueOf(idGenerator.incrementAndGet());
    }

    /**
     * 异步处理商品的推荐逻辑
     */
    private void processItemForRecommendationAsync(String feedbackId, String userId, String orderId, String productId, String feedback) {
        // 使用异步处理，避免阻塞主流程
        Thread.startVirtualThread(() -> {
            try {
                // 更新状态为处理中
                updateFeedbackAnalysisStatus(feedbackId, "PROCESSING", null, null, null);

                // 获取商品信息
                StoreProductDO product = storeProductMapper.selectById(Long.valueOf(productId));
                if (product == null) {
                    log.warn("[processItemForRecommendationAsync][商品不存在：{}]", productId);
                    updateFeedbackAnalysisStatus(feedbackId, "FAILED", null, null, "商品信息不存在");
                    return;
                }

                // 检查是否是复购
                int purchaseCount = orderFeedbackMapper.countProductPurchase(userId, productId, orderId);
                boolean isRepeatPurchase = purchaseCount > 0;

                String historyFeedback = null;
                if (isRepeatPurchase) {
                    log.info("[processItemForRecommendationAsync][检测到复购，用户({})商品({})购买次数：{}]",
                            userId, productId, purchaseCount);

                    // 获取历史反馈
                    historyFeedback = orderFeedbackMapper.getLatestFeedback(userId, productId);
                    if (StrUtil.isNotBlank(historyFeedback)) {
                        log.info("[processItemForRecommendationAsync][找到历史反馈：{}]", historyFeedback);
                    }
                } else {
                    log.info("[processItemForRecommendationAsync][首次购买用户({})商品({})，生成配比建议]", userId, productId);
                }

                // 生成AI推荐并更新商品配比
                String aiResult = generateRecipeRecommendation(feedback, historyFeedback, product);

                // 检查AI结果是否有效
                if (StrUtil.isNotBlank(aiResult)) {
                    // 解析并更新商品配比
                    Map<String, List<String>> aiSpecs = parseAiSuggestion(aiResult);
                    if (!aiSpecs.isEmpty()) {
                        updateProductAttributes(Long.valueOf(productId), aiSpecs);
                    }

                    // 解析AI结果并保存到数据库
                    log.info("[processItemForRecommendationAsync][AI返回结果，反馈ID：{}, 结果：{}]", feedbackId, aiResult);
                    parseAndSaveAIResult(feedbackId, aiResult);
                } else {
                    log.warn("[processItemForRecommendationAsync][AI结果为空，跳过处理]");
                    updateFeedbackAnalysisStatus(feedbackId, "FAILED", null, null, "AI分析结果为空");
                }

            } catch (Exception e) {
                log.error("[processItemForRecommendationAsync][处理失败，反馈ID：{}]", feedbackId, e);
                updateFeedbackAnalysisStatus(feedbackId, "FAILED", null, null, "处理异常：" + e.getMessage());
            }
        });
    }

    /**
     * 更新反馈分析状态
     */
    private void updateFeedbackAnalysisStatus(String feedbackId, String status, String tip, String recipe, String aiSuggestion) {
        try {
            OrderFeedbackDO feedback = orderFeedbackMapper.selectById(feedbackId);
            if (feedback != null) {
                feedback.setAnalysisStatus(status);
                if (tip != null) {
                    feedback.setPersonalizedTip(tip);
                }
                if (recipe != null) {
                    feedback.setAdjustedRecipe(recipe);
                }
                if (aiSuggestion != null) {
                    feedback.setAiSuggestion(aiSuggestion);
                }
                if ("COMPLETED".equals(status)) {
                    feedback.setAnalysisTime(LocalDateTime.now());
                }
                orderFeedbackMapper.updateById(feedback);
            }
        } catch (Exception e) {
            log.error("[updateFeedbackAnalysisStatus][更新状态失败，反馈ID：{}]", feedbackId, e);
        }
    }

    /**
     * 解析并保存AI分析结果
     */
    private void parseAndSaveAIResult(String feedbackId, String aiResult) {
        try {
            String[] lines = aiResult.split("\\r?\\n");
            String personalizedTip = null;
            String adjustedRecipe = null;
            String aiSuggestion = null;

            if (lines.length >= 1) {
                personalizedTip = lines[0].trim();
            }
            if (lines.length >= 2) {
                adjustedRecipe = lines[1].trim();
            }
            if (lines.length > 2) {
                aiSuggestion = String.join(" ", java.util.Arrays.copyOfRange(lines, 2, lines.length)).trim();
            }

            // 如果没有AI建议内容，生成默认建议
            if (StrUtil.isBlank(aiSuggestion)) {
                aiSuggestion = "感谢您的反馈，我们已根据您的建议优化了产品配比";
            }

            updateFeedbackAnalysisStatus(feedbackId, "COMPLETED", personalizedTip, adjustedRecipe, aiSuggestion);

        } catch (Exception e) {
            log.error("[parseAndSaveAIResult][解析AI结果失败，反馈ID：{}]", feedbackId, e);
            updateFeedbackAnalysisStatus(feedbackId, "FAILED", null, null, "解析AI结果失败");
        }
    }

    /**
     * 使用DashScope OpenAI兼容模式生成配方推荐
     */
    private String generateRecipeRecommendation(String currentFeedback, String historyFeedback, StoreProductDO product) {
        if (StrUtil.isBlank(dashScopeProperties.getApiKey())) {
            log.warn("[generateRecipeRecommendation][DashScope API Key未配置，使用默认推荐生成]");
            return generateDefaultRecommendation(currentFeedback, product);
        }

        try {
            // 获取商品当前属性规格
            Map<String, Object> attrDetails = appStoreProductAttrService.getProductAttrDetail(product.getId());
            List<?> productAttr = (List<?>) attrDetails.get("productAttr");

            // 构造prompt
            String prompt = buildPromptWithCurrentSpecs(currentFeedback, historyFeedback, product, productAttr);

            // 使用OpenAI兼容的HTTP API调用DashScope
            return callDashScopeOpenAICompatible(prompt);

        } catch (Exception e) {
            log.error("[generateRecipeRecommendation][生成推荐时发生异常]", e);
            // 返回默认推荐而不是抛出异常
            return generateDefaultRecommendation(currentFeedback, product);
        }
    }

    /**
     * 调用DashScope OpenAI兼容API
     */
    private String callDashScopeOpenAICompatible(String prompt) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();

            // 构建请求体
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("model", "qwen-plus");

            List<Map<String, String>> messages = new ArrayList<>();
            Map<String, String> userMessage = new HashMap<>();
            userMessage.put("role", "user");
            userMessage.put("content", prompt);
            messages.add(userMessage);
            requestBody.put("messages", messages);

            String jsonBody = objectMapper.writeValueAsString(requestBody);

            // 创建HTTP客户端
            HttpClient client = HttpClient.newHttpClient();

            // 创建HTTP请求
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create("https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions"))
                    .header("Content-Type", "application/json")
                    .header("Authorization", "Bearer " + dashScopeProperties.getApiKey())
                    .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
                    .build();

            // 发送请求
            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

            log.info("[callDashScopeOpenAICompatible][API响应状态码：{}]", response.statusCode());
            log.info("[callDashScopeOpenAICompatible][API响应内容：{}]", response.body());

            if (response.statusCode() == 200) {
                JsonNode responseJson = objectMapper.readTree(response.body());
                JsonNode choices = responseJson.get("choices");

                if (choices != null && choices.isArray() && choices.size() > 0) {
                    JsonNode message = choices.get(0).get("message");
                    if (message != null && message.has("content")) {
                        String content = message.get("content").asText();
                        if (StrUtil.isNotBlank(content)) {
                            log.info("[callDashScopeOpenAICompatible][AI调用成功]");
                            return content;
                        }
                    }
                }
            }

            log.warn("[callDashScopeOpenAICompatible][AI响应格式异常或内容为空]");
            // 从prompt中提取关键反馈信息来生成默认推荐
            return extractFeedbackAndGenerateDefault(prompt);

        } catch (Exception e) {
            log.error("[callDashScopeOpenAICompatible][HTTP调用异常]", e);
            // 从prompt中提取关键反馈信息来生成默认推荐
            return extractFeedbackAndGenerateDefault(prompt);
        }
    }

    /**
     * 从prompt中提取反馈信息并生成默认推荐
     */
    private String extractFeedbackAndGenerateDefault(String prompt) {
        // 简单地从prompt中提取用户反馈部分
        // prompt格式包含"用户当前反馈："的部分
        String feedback = "";
        if (prompt.contains("用户当前反馈：")) {
            int start = prompt.indexOf("用户当前反馈：");
            int end = prompt.indexOf("\n\n", start);
            if (end > start) {
                feedback = prompt.substring(start + "用户当前反馈：".length(), end).trim();
            }
        }

        if (StrUtil.isBlank(feedback)) {
            // 如果无法提取，使用通用推荐
            return "感谢您的反馈，我们会持续优化产品\n温度:少冰,热;甜度:少糖,多糖,默认";
        }

        return generateDefaultRecommendation(feedback, null);
    }

    /**
     * 生成默认推荐（当AI调用失败时使用）
     */
    private String generateDefaultRecommendation(String currentFeedback, StoreProductDO product) {
        if (product != null) {
            log.info("[generateDefaultRecommendation][使用默认推荐逻辑，商品：{}]", product.getStoreName());
        } else {
            log.info("[generateDefaultRecommendation][使用默认推荐逻辑，无商品信息]");
        }

        // 简单的关键词匹配生成推荐
        String lowerFeedback = currentFeedback.toLowerCase();

        if (lowerFeedback.contains("甜") || lowerFeedback.contains("糖")) {
            return "甜度已调低\n温度:少冰,热;甜度:少少糖,少糖,多糖,默认\n根据您的反馈，我们为拿铁添加了少少糖选项，让您有更多甜度选择";
        } else if (lowerFeedback.contains("冰") || lowerFeedback.contains("凉") || lowerFeedback.contains("冷")) {
            return "温度已调整\n温度:去冰,少冰,热;甜度:少糖,多糖,默认\n根据您的反馈，我们为饮品添加了去冰选项，让您有更多温度选择";
        } else if (lowerFeedback.contains("苦") || lowerFeedback.contains("浓")) {
            return "浓度已优化\n温度:少冰,热;甜度:多糖,默认;浓度:正常,淡一点\n根据您的反馈，我们调整了浓度选项，让口感更平衡";
        } else if (lowerFeedback.contains("酸")) {
            return "口感已平衡\n温度:少冰,热;甜度:多糖,默认\n根据您的反馈，我们优化了甜度配比来平衡酸度";
        } else {
            return "感谢您的反馈\n温度:少冰,热;甜度:少糖,多糖,默认\n感谢您的反馈，我们会持续优化产品口感和配比";
        }
    }

    /**
     * 构造包含当前配比的DashScope调用prompt
     */
    private String buildPromptWithCurrentSpecs(String currentFeedback, String historyFeedback, StoreProductDO product, List<?> productAttr) {
        String currentSpecs = formatProductAttr(productAttr);

        return String.format(
                "你是一个饮品配方智能助手。根据用户反馈优化商品配比。\n" +
                "商品名称：%s\n" +
                "当前配比：%s\n" +
                "用户当前反馈：%s\n" +
                "历史反馈：%s\n\n" +
                "请分析用户反馈，输出三行内容：\n" +
                "第一行：个性化提示（如：甜度已调低）\n" +
                "第二行：优化后的完整配比（格式：温度:少冰,热;甜度:少糖,多糖,默认）\n" +
                "第三行：详细建议说明（如：根据您的反馈，我们为饮品添加了新的选项）\n\n" +
                "要求：\n" +
                "1. 保留原有的所有选项\n" +
                "2. 根据反馈智能添加新的选项（如用户说太甜，可添加\"少少糖\"）\n" +
                "3. 每行一个内容，共三行\n" +
                "4. 使用中文冒号：和逗号\n" +
                "5. 第二行必须是标准的配比格式",
                product.getStoreName(),
                currentSpecs != null ? currentSpecs : "无配比信息",
                currentFeedback,
                historyFeedback != null ? historyFeedback : "无历史反馈"
        );
    }

    /**
     * 格式化商品属性为文本
     */
    private String formatProductAttr(List<?> productAttr) {
        if (productAttr == null || productAttr.isEmpty()) {
            return "无配比信息";
        }

        StringBuilder sb = new StringBuilder();
        try {
            for (Object attr : productAttr) {
                if (attr != null) {
                    // 简化处理，使用toString方法获取属性信息
                    String attrStr = attr.toString();
                    String attrName = "";
                    String attrValues = "";

                    // 尝试从字符串中提取属性名和值（这是一个简化的实现）
                    if (attrStr.contains("attrName")) {
                        // 实际项目中可能需要使用反射或其他方式获取属性值
                        log.debug("[formatProductAttr][处理属性：{}]", attrStr);
                        // 这里暂时使用默认值，实际应该解析对象获取
                        attrName = "未知属性";
                        attrValues = "未知值";
                    }

                    if (StrUtil.isNotBlank(attrName) && StrUtil.isNotBlank(attrValues)) {
                        sb.append(attrName).append(":").append(attrValues).append(";");
                    }
                }
            }
        } catch (Exception e) {
            log.warn("[formatProductAttr][格式化商品属性失败]", e);
            return "配比信息解析失败";
        }

        return sb.toString().replaceAll(";*$", "");
    }

    /**
     * 解析AI响应并更新商品配比
     */
    private void parseAndUpdateProductSpecification(String aiResponse, StoreProductDO product) {
        try {
            // 清理AI响应，移除可能的格式字符
            String cleanedResponse = aiResponse.trim()
                    .replace("，", ",")
                    .replace("：", ":");

            log.info("[parseAndUpdateProductSpecification][商品({})AI响应：{}]", product.getStoreName(), cleanedResponse);

            // 解析AI建议的配比
            Map<String, List<String>> aiSpecs = parseAiSuggestion(cleanedResponse);
            if (aiSpecs.isEmpty()) {
                log.warn("[parseAndUpdateProductSpecification][未能解析出有效配比：{}]", cleanedResponse);
                return;
            }

            // 获取当前商品配比
            Map<String, Object> attrDetails = appStoreProductAttrService.getProductAttrDetail(product.getId());
            List<?> productAttr = (List<?>) attrDetails.get("productAttr");
            Map<String, List<String>> currentSpecs = parseProductAttrToMap(productAttr);

            // 合并配比
            Map<String, List<String>> mergedSpecs = mergeSpecifications(currentSpecs, aiSpecs);

            // 更新商品属性
            updateProductAttributes(product.getId(), mergedSpecs);

            log.info("[parseAndUpdateProductSpecification][商品({})配比更新成功] 新配比：{}",
                    product.getStoreName(),
                    toTextFormat(mergedSpecs));

        } catch (Exception e) {
            log.error("[parseAndUpdateProductSpecification][更新商品配比失败：{}]", product.getStoreName(), e);
        }
    }

    /**
     * 解析商品属性为Map格式
     */
    private Map<String, List<String>> parseProductAttrToMap(List<?> productAttr) {
        Map<String, List<String>> specs = new LinkedHashMap<>();

        if (productAttr == null || productAttr.isEmpty()) {
            return specs;
        }

        try {
            for (Object attr : productAttr) {
                if (attr != null) {
                    // 简化处理，暂时使用默认值
                    // 实际项目中应该通过反射或其他方式获取对象属性
                    String attrStr = attr.toString();
                    String attrName = "未知属性";
                    String attrValues = "未知值";

                    // 如果是StoreProductAttrDO类型，可以直接获取
                    if (attr instanceof StoreProductAttrDO) {
                        StoreProductAttrDO productAttrDO = (StoreProductAttrDO) attr;
                        attrName = productAttrDO.getAttrName();
                        attrValues = productAttrDO.getAttrValues();
                    }

                    if (StrUtil.isNotBlank(attrName) && StrUtil.isNotBlank(attrValues)) {
                        List<String> values = Arrays.asList(attrValues.split(","));
                        specs.put(attrName, values);
                    }
                }
            }
        } catch (Exception e) {
            log.warn("[parseProductAttrToMap][解析商品属性失败]", e);
        }

        return specs;
    }

    /**
     * 更新商品属性
     */
    private void updateProductAttributes(Long productId, Map<String, List<String>> mergedSpecs) {
        try {
            // 获取现有的商品属性
            List<StoreProductAttrDO> existingAttrs = storeProductAttrMapper.selectList(
                    "product_id", productId);

            // 创建属性名到属性对象的映射
            Map<String, StoreProductAttrDO> attrMap = new HashMap<>();
            for (StoreProductAttrDO attr : existingAttrs) {
                attrMap.put(attr.getAttrName(), attr);
            }

            // 更新或创建属性
            for (Map.Entry<String, List<String>> entry : mergedSpecs.entrySet()) {
                String attrName = entry.getKey();
                List<String> attrValues = entry.getValue();

                StoreProductAttrDO attr = attrMap.get(attrName);
                if (attr != null) {
                    // 更新现有属性
                    String newValues = String.join(",", attrValues);
                    if (!newValues.equals(attr.getAttrValues())) {
                        attr.setAttrValues(newValues);
                        storeProductAttrMapper.updateById(attr);
                        log.info("[updateProductAttributes][更新属性：{} = {}]", attrName, newValues);
                    }
                } else {
                    // 创建新属性
                    StoreProductAttrDO newAttr = StoreProductAttrDO.builder()
                            .productId(productId)
                            .attrName(attrName)
                            .attrValues(String.join(",", attrValues))
                            .build();
                    storeProductAttrMapper.insert(newAttr);
                    log.info("[updateProductAttributes][创建新属性：{} = {}]", attrName, String.join(",", attrValues));
                }
            }

        } catch (Exception e) {
            log.error("[updateProductAttributes][更新商品属性失败，productId：{}]", productId, e);
            throw new RuntimeException("更新商品属性失败", e);
        }
    }

    @Override
    public List<FeedbackAnalysisRespVO> getUserFeedbackAnalysis(String userId) {
        List<OrderFeedbackDO> feedbacks = orderFeedbackMapper.selectList(
                OrderFeedbackDO::getUserId, userId);

        return feedbacks.stream()
                .sorted((f1, f2) -> f2.getCreateTime().compareTo(f1.getCreateTime()))
                .map(this::convertToAnalysisRespVO)
                .toList();
    }

    @Override
    public FeedbackAnalysisRespVO getFeedbackAnalysis(String feedbackId, String userId) {
        OrderFeedbackDO feedback = orderFeedbackMapper.selectById(feedbackId);
        if (feedback == null) {
            throw new ServiceException(400, "反馈记录不存在");
        }
        if (!feedback.getUserId().equals(userId)) {
            throw new ServiceException(403, "无权限查看该反馈记录");
        }

        return convertToAnalysisRespVO(feedback);
    }

    /**
     * 转换为分析结果响应VO
     */
    private FeedbackAnalysisRespVO convertToAnalysisRespVO(OrderFeedbackDO feedback) {
        FeedbackAnalysisRespVO respVO = new FeedbackAnalysisRespVO();
        respVO.setFeedbackId(feedback.getId());
        respVO.setOrderId(feedback.getOrderId());
        respVO.setProductId(feedback.getProductId());
        respVO.setProductName(feedback.getProductName());
        respVO.setUserFeedback(feedback.getMessage());
        respVO.setAnalysisStatus(feedback.getAnalysisStatus());
        respVO.setPersonalizedTip(feedback.getPersonalizedTip());
        respVO.setAdjustedRecipe(feedback.getAdjustedRecipe());
        respVO.setAiSuggestion(feedback.getAiSuggestion());
        respVO.setAnalysisTime(feedback.getAnalysisTime());
        respVO.setIsRepeatPurchase(feedback.getIsRepeatPurchase());

        // 解析配比变更详情
        respVO.setRecipeChanges(parseRecipeChanges(feedback));

        return respVO;
    }

    /**
     * 解析配比变更详情
     */
    private List<FeedbackAnalysisRespVO.RecipeChangeDetail> parseRecipeChanges(OrderFeedbackDO feedback) {
        List<FeedbackAnalysisRespVO.RecipeChangeDetail> changes = new ArrayList<>();

        if (StrUtil.isNotBlank(feedback.getAdjustedRecipe())) {
            try {
                // 调整后的配比
                Map<String, List<String>> adjustedSpecs = parseAiSuggestion(feedback.getAdjustedRecipe());

                // 获取商品原始配比
                Map<String, List<String>> originalSpecs = getCurrentProductSpecs(feedback.getProductId());

                // 对比分析生成变更详情
                for (Map.Entry<String, List<String>> entry : adjustedSpecs.entrySet()) {
                    String category = entry.getKey();
                    List<String> newValues = entry.getValue();

                    List<String> originalValues = originalSpecs.get(category);
                    if (originalValues == null) {
                        // 这是新增的配比类别
                        originalValues = new ArrayList<>();
                    }

                    // 找出新增的选项
                    for (String newValue : newValues) {
                        if (!originalValues.contains(newValue.trim())) {
                            FeedbackAnalysisRespVO.RecipeChangeDetail change = new FeedbackAnalysisRespVO.RecipeChangeDetail();
                            change.setCategory(category);
                            change.setChangeType("ADD");
                            change.setOriginalRecipe(String.join(",", originalValues));
                            change.setAdjustedRecipe(String.join(",", newValues));
                            change.setDescription("新增" + category + "选项：" + newValue);
                            changes.add(change);
                        }
                    }

                    // 找出被移除的选项（如果有的话）
                    for (String originalValue : originalValues) {
                        if (!newValues.contains(originalValue.trim())) {
                            FeedbackAnalysisRespVO.RecipeChangeDetail change = new FeedbackAnalysisRespVO.RecipeChangeDetail();
                            change.setCategory(category);
                            change.setChangeType("REMOVE");
                            change.setOriginalRecipe(originalValue);
                            change.setAdjustedRecipe("");
                            change.setDescription("移除" + category + "选项：" + originalValue);
                            changes.add(change);
                        }
                    }
                }

                log.info("[parseRecipeChanges][解析配比变更完成，反馈ID：{}, 变更数量：{}]", feedback.getId(), changes.size());

            } catch (Exception e) {
                log.warn("[parseRecipeChanges][解析配比变更失败，反馈ID：{}]", feedback.getId(), e);
            }
        }

        return changes;
    }

    /**
     * 获取商品的当前配比规格
     */
    private Map<String, List<String>> getCurrentProductSpecs(String productId) {
        Map<String, List<String>> specs = new LinkedHashMap<>();

        try {
            // 获取商品属性
            Map<String, Object> attrDetails = appStoreProductAttrService.getProductAttrDetail(Long.valueOf(productId));
            List<?> productAttr = (List<?>) attrDetails.get("productAttr");

            return parseProductAttrToMap(productAttr);

        } catch (Exception e) {
            log.warn("[getCurrentProductSpecs][获取商品配比失败，productId：{}]", productId, e);
        }

        return specs;
    }

    /**
     * 解析AI建议的配比
     */
    private Map<String, List<String>> parseAiSuggestion(String aiResponse) {
        Map<String, List<String>> specs = new LinkedHashMap<>();

        if (StrUtil.isBlank(aiResponse)) {
            return specs;
        }

        try {
            String[] parts = aiResponse.split(";");
            for (String part : parts) {
                part = part.trim();
                if (part.contains(":")) {
                    String[] keyValue = part.split(":", 2);
                    if (keyValue.length == 2) {
                        String key = keyValue[0].trim();
                        String values = keyValue[1].trim();
                        if (StrUtil.isNotBlank(key) && StrUtil.isNotBlank(values)) {
                            List<String> valueList = Arrays.asList(values.split(","));
                            specs.put(key, valueList);
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.warn("[parseAiSuggestion][解析AI配比建议失败：{}]", aiResponse, e);
        }

        return specs;
    }

    /**
     * 合并配比规格
     */
    private Map<String, List<String>> mergeSpecifications(Map<String, List<String>> currentSpecs, Map<String, List<String>> aiSpecs) {
        Map<String, List<String>> merged = new LinkedHashMap<>(currentSpecs);

        for (Map.Entry<String, List<String>> entry : aiSpecs.entrySet()) {
            String key = entry.getKey();
            List<String> aiValues = entry.getValue();

            if (merged.containsKey(key)) {
                // 合并现有配比
                List<String> currentValues = merged.get(key);
                List<String> combinedValues = new ArrayList<>(currentValues);

                // 添加AI建议的新值
                for (String aiValue : aiValues) {
                    if (!combinedValues.contains(aiValue.trim())) {
                        combinedValues.add(aiValue.trim());
                    }
                }

                merged.put(key, combinedValues);
            } else {
                // 添加新的配比类型
                merged.put(key, new ArrayList<>(aiValues));
            }
        }

        return merged;
    }

    /**
     * 将配比Map转换为文本格式
     */
    private String toTextFormat(Map<String, List<String>> specs) {
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, List<String>> entry : specs.entrySet()) {
            sb.append(entry.getKey()).append(":").append(String.join(",", entry.getValue())).append(";");
        }
        return sb.toString().replaceAll(";*$", "");
    }
}